﻿using System;
using System.Collections.Generic;
using SLS.ExClassLib.MultiThreading.Threading.ThreadPools.TaskItems;

namespace SLS.ExClassLib.MultiThreading.Threading.ThreadPools.TaskQueues
{
    public class PriorityTaskQueue : ITaskQueue
    {
        private List<Queue<WorkItem>> _queues = new List<Queue<WorkItem>>();
        private int _workItemsCount;

        public PriorityTaskQueue()
        {
            InitializeQueues();
        }

        private void InitializeQueues()
        {
            _queues = new List<Queue<WorkItem>>(Enum.GetNames(typeof (TaskItemPriority)).Length);
            for (int i = 0; i < _queues.Capacity; i++)
            {
                _queues.Add(new Queue<WorkItem>());
            }
        }

        #region Implementation of ITaskQueue

        public int Count
        {
            get { return _workItemsCount; }
        }

        public void Enqueue(WorkItem item)
        {
            var priority = (int) item.Priority;
            if (priority >= _queues.Count)
                throw new ArgumentException(string.Format("Invalid TaskItemPriority: {0}", item.Priority));
            _queues[priority].Enqueue(item);
            _workItemsCount++;
        }

        public WorkItem Dequeue()
        {
            for (int i = _queues.Count - 1; i >= 0; i--)
            {
                if (_queues[i].Count == 0)
                    continue;
                WorkItem workItem = _queues[i].Dequeue();
                _workItemsCount--;
                return workItem;
            }
            return null;
        }

        #endregion
    }
}